package com.ziven.learn.dispatch;

import android.util.Pair;

import com.ziven.easygo.design.funnel.FilterHelper;
import com.ziven.easygo.util.EasyUtils;
import com.ziven.easygo.util.ListMultiCarry;
import com.ziven.easygo.util.LogHelper;
import com.ziven.easygo.util.MapMultiCarry;
import com.ziven.easygo.util.ResourceUtils;
import com.ziven.easygo.util.ThreadUtils;
import com.ziven.learn.LearnInterface;

import java.util.List;
import java.util.Map;

/**
 * @author Ziven
 */
public class EasyGoLearn implements LearnInterface {

    private static final String SP_KEY_1 = "sp_key_1";
    private static final String SP_KEY_2 = "sp_key_2";
    private static final String SP_KEY_3 = "sp_key_3";
    private static final String SP_KEY_4 = "sp_key_4";
    private static final String SP_KEY_5 = "sp_key_5";
    private static final String SP_KEY_6 = "sp_key_6";
    private static final String SP_KEY_7 = "sp_key_7";
    private static final String SP_KEY_8 = "sp_key_8";
    private static final int SP_VALUE_1 = 1;
    private static final int SP_VALUE_2 = 2;
    private static final int SP_VALUE_3 = 3;
    private static final int SP_VALUE_4 = 4;
    private static final String SP_VALUE_5 = "s5";
    private static final String SP_VALUE_6 = "s6";
    private static final String SP_VALUE_7 = "s7";
    private static final String SP_VALUE_8 = "s8";

    @Override
    public void learn() {
        learnResourceUtilsSpUse();
        learnThreadUtils(3);
        learnEasyFilter();
    }

    private void learnEasyFilter() {
        FilterHelper.get()
                .withThis()
                .add(grain -> {
                    log("learnEasyFilter 1:" + grain);
                    grain.setGain("Filter 1");
                })
                .add(grain -> {
                    log("learnEasyFilter 2:" + grain);
                    grain.setGain("Filter 2");
                })
                .add(grain -> {
                    log("learnEasyFilter 3:" + grain);
                    grain.setGain("Filter 3");
                });
        FilterHelper.get().filterThis();
    }

    private void learnResourceUtilsSpUse() {
        //单独设置SP值
        ResourceUtils.ofSp().applyValue(SP_KEY_1, SP_VALUE_1);

        //传递Pair进行设置
        ResourceUtils.ofSp().applyValues(
                Pair.create(SP_KEY_2, SP_VALUE_2),
                Pair.create(SP_KEY_3, SP_VALUE_3));

        //获取Sp-edit进行设置
        ResourceUtils.sp().edit()
                .putString(SP_KEY_6, SP_VALUE_6)
                .apply();

        //传递Map进行设置
        Map<String, Object> map = EasyUtils.newMap();
        map.put(SP_KEY_4, SP_VALUE_4);
        map.put(SP_KEY_5, SP_VALUE_5);
        ResourceUtils.ofSp().applyValues(map);

        //传递List进行设置
        List<Pair<String, Object>> list = EasyUtils.newList(
                Pair.create(SP_KEY_7, SP_VALUE_7),
                Pair.create(SP_KEY_8, SP_VALUE_8));
        ResourceUtils.ofSp().applyValues(list);

        //返回Array
        LogHelper logHelper1 = LogHelper.of("learnResourceUtilsSpUse ").join("方法1:\n");
        ResourceUtils.ofSp().obtainValues(values -> EasyUtils.forEach(values, logHelper1::join),
                Pair.create(Integer.class, SP_KEY_1),
                Pair.create(Integer.class, SP_KEY_2),
                Pair.create(Integer.class, SP_KEY_3),
                Pair.create(Integer.class, SP_KEY_4),
                Pair.create(String.class, SP_KEY_5),
                Pair.create(String.class, SP_KEY_6),
                Pair.create(String.class, SP_KEY_7),
                Pair.create(String.class, SP_KEY_8));
        logHelper1.print();

        //返回List
        LogHelper logHelper2 = LogHelper.of("learnResourceUtilsSpUse ").join("方法2:\n");
        ResourceUtils.ofSp().obtainValues(Integer.class,
                (ListMultiCarry<Integer>) values -> EasyUtils.forEach(values, logHelper2::join),
                SP_KEY_1,
                SP_KEY_2,
                SP_KEY_3);
        logHelper2.print();

        //返回Map
        LogHelper logHelper3 = LogHelper.of("learnResourceUtilsSpUse ").join("方法3:\n");
        ResourceUtils.ofSp().obtainValues(String.class,
                (MapMultiCarry<String, String>) values -> EasyUtils.forEach(values, ((key, value) -> logHelper3.join(key).join(value))),
                SP_KEY_5,
                SP_KEY_6,
                SP_KEY_7,
                SP_KEY_8);
        logHelper3.print();
    }

    private void learnThreadUtils(int testWhat) {
        log("learnThreadUtils testWhat=" + testWhat);
        if(testWhat == 0) {
            ThreadUtils.timesInterval(5, 1000, times
                    -> log("learnThreadUtils 方法1:", times));
            return;
        }

        if(testWhat == 1) {
            ThreadUtils.timesInterval().interval(1000).carry(times
                    -> log("learnThreadUtils 方法2:", times))
                    .start(5);
            return;
        }

        if(testWhat == 2) {
            //串行
            ThreadUtils.ThreadEasyGo.of().workerThread(value -> {
                log("learnThreadUtils=" + value);
                return "Step 1:" + Thread.currentThread();
            }).workerThread(value -> {
                log("learnThreadUtils=" + value);
                return "Step 2:" + Thread.currentThread();
            }).workerThread(value -> {
                log("learnThreadUtils=" + value);
                return "Step 3:" + Thread.currentThread();
            }).mainThread(value -> {
                log("learnThreadUtils=" + value);
                return "Step 4:" + Thread.currentThread();
            }).mainThread(value -> {
                log("learnThreadUtils=" + value);
                return null;
            }).serial("step 0:" +  Thread.currentThread());
            return;
        }

        if(testWhat == 3) {
            //并行
            ThreadUtils.ThreadEasyGo.of().workerThread(value -> {
                log("learnThreadUtils 1=" + value);
                return "Step 1:" + Thread.currentThread();
            }).workerThread(value -> {
                log("learnThreadUtils 2=" + value);
                return "Step 2:" + Thread.currentThread();
            }).workerThread(value -> {
                log("learnThreadUtils 3=" + value);
                return "Step 3:" + Thread.currentThread();
            }).mainThread(value -> {
                log("learnThreadUtils 4=" + value);
                return "Step 4:" + Thread.currentThread();
            }).mainThread(value -> {
                log("learnThreadUtils 5=" + value);
                return "Step 5:" + Thread.currentThread();
            }).mainThread(value -> {
                log("learnThreadUtils 6=" + value);
                return "Step 6:" + Thread.currentThread();
            }).mainThread(value -> {
                log("learnThreadUtils 7=" + value);
                return "Step 7:" + Thread.currentThread();
            }).mainThread(value -> {
                log("learnThreadUtils 8=" + value);
                return "Step 8:" + Thread.currentThread();
            }).mainThread(value -> {
                log("learnThreadUtils 9=" + value);
                return "Step 9:" + Thread.currentThread();
            }).parallelWorker(new ThreadUtils.MultipleTransfer() {
                @Override
                public void singleTransfer(int position, Object value) {
                    log("learnThreadUtils 6=" + position + " myself:" + Thread.currentThread() + " value=" + value);
                }

                @Override
                public void multipleTransfer(Object... values) {
                    EasyUtils.forEach(values, value -> {
                        log("learnThreadUtils 7=myself:" + Thread.currentThread() + " value=" + value);
                    });
                }
            }, "param-1", "param-2", "param-3", "param-4", "param-5", "param-6", "param-7");
            return;
        }
    }
}
